package com.gitee.wsl.func.operator

/**
 * Represents an operation on a single `double`-valued operand that produces
 * a `double`-valued result.  This is the primitive type specialization of
 * [UnaryOperator] for `double`.
 *
 *
 * This is a [functional interface](package-summary.html)
 * whose functional method is [.applyAsDouble].
 *
 * @see UnaryOperator
 *
 * @since 1.8
 */
fun interface DoubleUnaryOperator {
    /**
     * Applies this operator to the given operand.
     *
     * @param operand the operand
     * @return the operator result
     */
    fun applyAsDouble(operand: Double): Double

    /**
     * Returns a composed operator that first applies the `before`
     * operator to its input, and then applies this operator to the result.
     * If evaluation of either operator throws an exception, it is relayed to
     * the caller of the composed operator.
     *
     * @param before the operator to apply before this operator is applied
     * @return a composed operator that first applies the `before`
     * operator and then applies this operator
     * @throws NullPointerException if before is null
     *
     * @see .andThen
     */
    fun compose(before: DoubleUnaryOperator): DoubleUnaryOperator {
        return DoubleUnaryOperator { v: Double -> applyAsDouble(before.applyAsDouble(v)) }
    }

    /**
     * Returns a composed operator that first applies this operator to
     * its input, and then applies the `after` operator to the result.
     * If evaluation of either operator throws an exception, it is relayed to
     * the caller of the composed operator.
     *
     * @param after the operator to apply after this operator is applied
     * @return a composed operator that first applies this operator and then
     * applies the `after` operator
     * @throws NullPointerException if after is null
     *
     * @see .compose
     */
    fun andThen(after: DoubleUnaryOperator): DoubleUnaryOperator {
        return DoubleUnaryOperator { t: Double -> after.applyAsDouble(applyAsDouble(t)) }
    }

    companion object {
        /**
         * Returns a unary operator that always returns its input argument.
         *
         * @return a unary operator that always returns its input argument
         */
        fun identity(): DoubleUnaryOperator {
            return DoubleUnaryOperator { t: Double -> t }
        }
    }
}
